package com.faithnmn.utils;

import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import android.content.Context;
import android.location.Location;
import android.os.AsyncTask;
import android.util.Log;

import com.faithnmn.utils.weather.GotLocationCallback;
import com.faithnmn.utils.weather.GotWeatherCallback;
import com.faithnmn.utils.weather.HttpLa;
import com.faithnmn.utils.weather.HttpLa.LocationResult;
import com.faithnmn.utils.weather.LocationParser;
import com.faithnmn.utils.weather.WeatherConstants;
import com.faithnmn.utils.weather.WeatherUtil;
import com.faithnmn.utils.weather.YahooParser;
import com.faithnmn.utils.weather.model.Weather;

public class WeatherHelper {
	private Context context;
	private LocationResult locationResult;
	private LocationResult locationOnlyResult;
	private HttpLa myLocation = new HttpLa();
	private boolean cancelRequest = false;
	private GotWeatherCallback weatherCallback;
	private GotLocationCallback locationCallback;
	public WeatherHelper(Context context) {
		this.context = context;
	}
	
	public void cancelRequest(){
		this.cancelRequest = true;
	}
	
	public void getLAOnly(GotLocationCallback locationCallback){
		this.locationCallback = locationCallback;
		Thread thread = new Thread(new Runnable() {
			
			@Override
			public void run() {
				WeatherHelper.this.cancelRequest = false;
				locationOnlyResult = new LocationResult(){
				    @Override
				        public void gotLocation(Location location){
				    	if(cancelRequest){
				    		return;
				    	}
				    	if(location!=null){
				    		Log.e("Location","latitude & longitude:"+location.getLatitude()+","+location.getLongitude());
					    	String locationUrl = WeatherUtil.formatString(location.getLatitude(), location.getLongitude());
					    	new ProcessLAOnlyAsync().execute(new String[]{locationUrl});
				    	}else{
				    		if(WeatherHelper.this.locationCallback!=null){
				    			WeatherHelper.this.locationCallback.onGotLocation(null);
				    		}
				    	}
				    }
				};
				new GetLAAsync().execute(true);
			}
		});
		thread.start();
	}
	
	public void getWeather(GotWeatherCallback weatherCallback){
		this.cancelRequest = false;
		this.weatherCallback = weatherCallback;
		locationResult = new LocationResult(){
		    @Override
		        public void gotLocation(Location location){
		    	if(cancelRequest){
		    		return;
		    	}
				try {
					String locationUrl = WeatherUtil.formatString(location.getLatitude(), location.getLongitude());
					new ProcessLAAsync().execute(new String[]{locationUrl});
				} catch (Exception ex) {
					ex.printStackTrace();
				}
		    }
		};
		new GetLAAsync().execute(false);
	}
	private class GetLAAsync extends AsyncTask<Boolean, Void, Void>{
		private boolean locationOnly = false;
		@Override
		protected Void doInBackground(Boolean... params) {
			locationOnly = params[0];
			return null;
		}
		@Override
		protected void onPostExecute(Void result) {
			myLocation.getLocation(context, locationOnly?locationOnlyResult:locationResult);
		}
	}
	
	private class ProcessLAOnlyAsync extends AsyncTask<String, Void, Void>{

		@Override
		protected Void doInBackground(String... params) {
			try {
				HttpClient httpClient = new DefaultHttpClient();
				HttpResponse response;
				try {
					response = httpClient.execute(new HttpGet(params[0]));
					HttpEntity entity = response.getEntity();
					com.faithnmn.utils.weather.model.Location gotLocation = LocationParser.parse(entity.getContent());
					if(locationCallback!=null){
						locationCallback.onGotLocation(gotLocation);
					}
				} catch (ClientProtocolException e) {
					e.printStackTrace();
					if(WeatherHelper.this.locationCallback != null){
						WeatherHelper.this.locationCallback.onGotLocation(null);
					}
				} catch (IOException e) {
					e.printStackTrace();
					if(WeatherHelper.this.locationCallback != null){
						WeatherHelper.this.locationCallback.onGotLocation(null);
					}
				}
			} catch (Exception ex) {
				ex.printStackTrace();
			}
			return null;
		}
		
	}
	
	private class ProcessLAAsync extends AsyncTask<String, Void, Void>{
		@Override
		protected Void doInBackground(String... params) {
			if(cancelRequest){
	    		return null;
	    	}
			HttpClient httpClient = new DefaultHttpClient();
			HttpResponse response;
			try {
				response = httpClient.execute(new HttpGet(params[0]));
				HttpEntity entity = response.getEntity();
				if(cancelRequest){
		    		return null;
		    	}
				String responseString = EntityUtils.toString(entity, "UTF-8");
				if(responseString.contains("<woeid>")){
					String woeid = responseString.substring(responseString.indexOf("<woeid>")+7, responseString.indexOf("</woeid>"));
					
					String weatherUrl = "http://weather.yahooapis.com/forecastrss?w="+woeid+"&u=c";
					response =  httpClient.execute(new HttpGet(weatherUrl));
					entity = response.getEntity();
//					responseString = EntityUtils.toString(entity, "UTF-8");
					try {
						Weather weather = YahooParser.parse(entity.getContent());
						if(weatherCallback != null){
							weatherCallback.onGotWeather(weather);
						}
//						JAXBContext context = JAXBContext.newInstance(Weather.class);
//			            Unmarshaller unmarshaller = context.createUnmarshaller();
//			            Weather track = (Weather) unmarshaller.unmarshal(file);
					} catch (IllegalStateException e) {
						e.printStackTrace();
						if(weatherCallback != null){
							weatherCallback.onGotWeather(null);
						}
					} catch (Exception e) {
						e.printStackTrace();
						if(weatherCallback != null){
							weatherCallback.onGotWeather(null);
						}
					}
				}else{
					Log.e("WeatherHelper", "Could not found WOEID.Location Result:"+responseString);
					if(weatherCallback != null){
						weatherCallback.onGotWeather(null);
					}
				}
			} catch (ClientProtocolException e) {
				e.printStackTrace();
				if(weatherCallback != null){
					weatherCallback.onGotWeather(null);
				}
			} catch (IOException e) {
				e.printStackTrace();
				if(weatherCallback != null){
					weatherCallback.onGotWeather(null);
				}
			}
			return null;
		}
		@Override
		protected void onPostExecute(Void result) {
		}
		
	}
}
